package cn.mw.cmdb.processor.zabbix;

import cn.mw.cmdb.entity.ItemNameMapperInfo;
import cn.mw.cmdb.entity.MacrosInfo;
import cn.mw.cmdb.enums.ChartTypeEnum;
import cn.mw.cmdb.enums.MonitorFlagStatus;
import cn.mw.cmdb.enums.MonitoringServerType;
import cn.mw.cmdb.enums.ZabbixItemEnum;
import cn.mw.cmdb.exception.CreateMonitorGroupException;
import cn.mw.cmdb.exception.HostCreatFailException;
import cn.mw.cmdb.exception.WarnParamTitleException;
import cn.mw.cmdb.exception.WarnTitleException;
import cn.mw.cmdb.mongoMapper.ItemNameMapper;
import cn.mw.cmdb.param.*;
import cn.mw.cmdb.param.zabbixResult.*;
import cn.mw.cmdb.processor.*;
import cn.mw.cmdb.util.CMDBTool;
import cn.mw.cmdb.util.SeverityUtils;
import cn.mw.components.mongodb.tool.CriteriaWrapper;
import cn.mw.main.api.common.ZabbixDubboService;
import cn.mw.microMonitorCommon.constants.ZabbixApiConstants;
import cn.mw.microMonitorCommon.constants.ZabbixItemConstant;
import cn.mw.microMonitorCommon.entity.UnitResult;
import cn.mw.microMonitorCommon.entity.zabbix.ApplicationDTO;
import cn.mw.microMonitorCommon.entity.zabbix.HostCreateParam;
import cn.mw.microMonitorCommon.entity.zabbix.MWZabbixAPIResult;
import cn.mw.microMonitorCommon.util.DateUtils;
import cn.mw.microMonitorCommon.util.SpringUtils;
import cn.mw.microMonitorCommon.util.UnitUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;

import static cn.mw.cmdb.enums.ChartTypeEnum.getChartEnumByName;
import static cn.mw.cmdb.enums.ChartTypeEnum.line;
import static cn.mw.cmdb.enums.ZabbixItemEnum.SYSTEM_UPTIME;
import static cn.mw.cmdb.service.impl.InstanceMonitorServiceImpl.MW_DISK_UTILIZATION;
import static cn.mw.cmdb.util.ItemNameFilterUtil.itemNameFilterBracket;
import static cn.mw.cmdb.util.ValConvertUtil.*;

@Slf4j
public class ZabbixMonitorProcessor extends MonitorProcessor {
    private static final Logger logger = LoggerFactory.getLogger("component-" + ZabbixMonitorProcessor.class.getName());

    private final static String NAME_KEY = "name";
    private final static String TASK_IDS = "taskids";
    private final static String UNITS_KEY = "units";
    private final static String DELAY_KEY = "delay";
    private final static String VALUE_TYPE_KEY = "value_type";
    private final static String VALUEMAPID_KEY = "valuemapid";
    private final static int maxHostIdNum = 200;

    private final static String itemCheckNowCode = "6";

    private final static int limit = 60;

    private final static String GROUP_IDS = "groupids";


    public static final String INTERFACE_DESCR = "INTERFACE_DESCR";
    public static final String INTERFACES_INFO = "INTERFACES_INFO";
    public static final String INTERFACES = "INTERFACES";

    public static final String DISK_UTILIZATION = "DISK_UTILIZATION";
    public static final String DISK_USED = "DISK_USED";
    public static final String DISK_FREE = "DISK_FREE";
    public static final String DISK_TOTAL = "DISK_TOTAL";
    //非法字符提示信息
    public static final String IncorrectCharactersKey = "Incorrect characters used for host name";
    public static final String HostNameAlreadyExistsKey = "Host with the same";

    public static final String itemPrefix = "MW_";
    public static final String templateKey = "templateId";
    public static final String valueKey = "value";
    public static final String macroKey = "macro";


    @Override
    public void monitor(MonitorParamContext context) {
        ZabbixUtils zabbixUtils = SpringUtils.getBean(ZabbixUtils.class);
        HostCreateParam hostCreateParam = zabbixUtils.transform(monitorValue, context);
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        List<HostCreateParam> hostCreateParamList = new ArrayList<>();
        hostCreateParamList.add(hostCreateParam);
        MWZabbixAPIResult result = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.HOST_BATCH_CREATE, monitorValue.getMonitorServerId(), hostCreateParamList);
        if (result != null && result.isFail()) {
            log.error("批量新增资产失败:" + result.getData());
            String errorMsg = IncorrectCharactersKey;
            if (result.getData() != null && result.getData().toString().indexOf(errorMsg) != -1) {
                Object[] args = new Object[]{errorMsg + result.getMessage() + ":" + result.getData()};
                throw new HostCreatFailException(args);
            }
            Object[] args = new Object[]{result.getMessage() + ":" + result.getData()};
            throw new HostCreatFailException(args);
        }
        monitorValue.setMonitorTypeName(hostCreateParam.getName());
        // 对应的mongo里面的instanceId
        String hostids = String.valueOf(result.getData());
        HostCreatResult hostCreatResult = JSONObject.parseObject(hostids, HostCreatResult.class);
        List<String> values = hostCreatResult.getHostids();
        if (null != values) {
            //只传了一个主机创建参数,只可能循环一次
            for (int i = 0; i < values.size(); i++) {
                String value = values.get(i);
                monitorValue.setMonitorType(MonitoringServerType.Zabbix.name());
                monitorValue.setMonitorTypeId(value);
            }
        }
    }

    @Override
    public void batchMonitor(MonitorParamContext context) {
        ZabbixUtils zabbixUtils = SpringUtils.getBean(ZabbixUtils.class);
        List<HostCreateParam> hostCreateParamList = zabbixUtils.transformBatch(monitorValueList, context);
        Map<Integer, MonitorValue> collect = monitorValueList.stream().collect(Collectors.toMap(s -> s.getBatchIndex(), s -> s, (o1, o2) -> o1));
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        logger.info("batchMonitor::" + hostCreateParamList);
        MWZabbixAPIResult result = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.HOST_BATCH_CREATE, mwTPServerTable.getId(), hostCreateParamList);
        if(result == null){
            log.error("批量新增资产失败:" + result);
            throw new HostCreatFailException(new Object[]{});
        }
        if (result != null && result.isFail()) {
            String message = strValueConvert(result.getData()) ;
            log.error("批量新增资产失败:" + message);
            String errorMsg = IncorrectCharactersKey;
            String alreadyExistsErrorMsg = HostNameAlreadyExistsKey;
            if (message.indexOf(errorMsg) != -1) {
                String[] split = message.split("\"");
                if(split.length > 1){
                    String hostName = split[1];
                    throw new WarnParamTitleException("host-name-incorrect-characters",hostName);
                }
            }
            if (message.indexOf(alreadyExistsErrorMsg) != -1) {
                String[] split = message.split("\"");
                if(split.length > 1){
                    String hostName = split[1];
                    throw new WarnParamTitleException("host-name-already-exists",hostName);
                }
                throw new WarnTitleException("host-name-already-exists");
            }
            Object[] args = new Object[]{result.getMessage() + ":" + message};
            throw new HostCreatFailException(args);
        }

        // 对应的mongo里面的instanceId
        String hostids = String.valueOf(result.getData());
        HostCreatResult hostCreatResult = JSONObject.parseObject(hostids, HostCreatResult.class);
        List<String> values = hostCreatResult.getHostids();
        if (null != values) {
            for (int i = 0; i < values.size(); i++) {
                String value = values.get(i);
                HostCreateParam hostCreateParam = hostCreateParamList.get(i);
                Integer batchIndex = hostCreateParam.getBatchIndex();
                if (collect != null && collect.containsKey(batchIndex)) {
                    MonitorValue monitorValueIndex = collect.get(batchIndex);
                    monitorValueIndex.setMonitorTypeName(hostCreateParam.getName());
                    monitorValueIndex.setMonitorType(MonitoringServerType.Zabbix.name());
                    monitorValueIndex.setMonitorTypeId(value);
                }

            }
        }
    }

    @Override
    public void removeMonitor(MonitorParamContext context) {
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        int monitorServerId = monitorValue.getMonitorServerId();
        List<String> ids = new ArrayList<>();
        ids.add(monitorValue.getMonitorTypeId());
        log.info("removeMonitor::monitorServerId:"+monitorServerId+";ids::"+ids);
        zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.HOST_DELETE, monitorServerId, ids);
    }

    @Override
    public List<MwMacros> getMacrosByTemplateId(MonitorParamContext context) {
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        Map<String, Object> mapParam = context.getMapParam();
        List<MacrosInfo> macrosList = new ArrayList<>();
        String templateId = strValueConvert(mapParam.get(templateKey));
        Object param = context.getParam();
        Map<String, List<MacrosInfo>> macroMap = new HashMap<>();
        Map<String, List<MacrosInfo>> collect;
        Map<String, List<MacrosInfo>> collectBak;
        if (param != null && param instanceof List) {
            macrosList = (List<MacrosInfo>) param;
            collect = macrosList.stream().filter(s -> !Strings.isNullOrEmpty(s.getMacro())).collect(Collectors.groupingBy(MacrosInfo::getMacro));
            collectBak = macrosList.stream().filter(s -> !Strings.isNullOrEmpty(s.getMacroBak())).collect(Collectors.groupingBy(MacrosInfo::getMacroBak));
        } else {
            collectBak = new HashMap<>();
            collect = new HashMap<>();
        }
        MWZabbixAPIResult result = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_MACROS_BY_TEMPLATE_ID, mwTPServerTable.getId(), templateId);
        List<MwMacros> macros = new ArrayList<>();
        if (result != null && !result.isFail()) {
            if (result.getData() != null) {
                List<Macros> macrosLists = JSONArray.parseArray(JSON.toJSONString(result.getData()), Macros.class);
                for (Macros macro : macrosLists) {
                    boolean isMacroBak = true;
                    if (collect != null && collect.containsKey(macro.getMacro())) {
                        isMacroBak = false;
                        macroMap = collect;
                    }
                    if (collectBak != null && collectBak.containsKey(macro.getMacro())) {
                        isMacroBak = true;
                        macroMap = collectBak;
                    }
                    if (CollectionUtils.isMapEmpty(macroMap) || !macroMap.containsKey(macro.getMacro())) {
                        continue;
                    }
                    List<MacrosInfo> macrosInfos = macroMap.get(macro.getMacro());
                    MacrosInfo macrosInfo = macrosInfos.get(0);
                    MwMacros macrosDTO = new MwMacros();
                    macrosDTO.setChMacro(macrosInfo.getChMacro());
                    if (isMacroBak) {
                        macrosDTO.setMacro(macrosInfo.getMacroBak());
                    } else {
                        macrosDTO.setMacro(macrosInfo.getMacro());
                    }
                    macrosDTO.setType(intValueConvert(macrosInfo.getMacroEncryption()));
                    macrosDTO.setValue(macro.getMacro());
                    macros.add(macrosDTO);
                }
            }
        }
        return macros;
    }

    /**
     * 获取资产状态
     *
     * @param context
     * @return Map<String, String> key为ServerId+hostId  value为
     */
    @Override
    public List<MwZabbixItemResultParam> getInstanceMonitorState(MonitorParamContext context) {
        List<MwZabbixItemResultParam> listParams = new ArrayList<>();
        QueryMonitorValue monitorParam = context.getQueryMonitorParam();
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        List<String> itemNames = ZabbixItemConstant.NEW_ASSETS_STATUS;
        if (monitorParam != null) {
            Integer serverId = monitorParam.getMonitorServerId();
            List<String> hostIds = monitorParam.getHostIds();
            MWZabbixAPIResult statusData = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.ITEM_GET_BY_SEARCH, serverId, itemNames, hostIds);
            if (statusData != null && !statusData.isFail() && statusData.getData() != null) {
                listParams = JSONArray.parseArray(String.valueOf(statusData.getData()), MwZabbixItemResultParam.class);
                for (MwZabbixItemResultParam node : listParams) {
                    node.setMonitorServerId(serverId);
                }
            }
        }

        return listParams;
    }

    /**
     * 修改主机监控状态
     *
     * @return
     */
    @Override
    public void updateHostState(MonitorParamContext context) {
        QueryMonitorValue queryMonitorParam = context.getQueryMonitorParam();
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        BatchEditorViewInstance param = (BatchEditorViewInstance) context.getParam();
        if (queryMonitorParam != null) {
            Integer serverId = queryMonitorParam.getMonitorServerId();
            //使用多线程处理多个zabbix服务的情况
            List<String> hostIds = queryMonitorParam.getHostIds();
            MonitorFlagStatus monitorStatus = param.getMonitorFlagStatus();
            zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.HOST_UPDATE, serverId, hostIds, monitorStatus.getStatus());
        }
    }

    /**
     * 批量删除监控主机
     *
     * @return
     */
    @Override
    public void batchDelMonitorAssets(MonitorParamContext context) {
        QueryMonitorValue queryMonitorParam = context.getQueryMonitorParam();
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        if (queryMonitorParam != null) {
            Integer serverId = queryMonitorParam.getMonitorServerId();
            //使用多线程处理多个zabbix服务的情况
            List<String> hostIds = queryMonitorParam.getHostIds();
            zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.HOST_DELETE, serverId, hostIds);
        }
    }


    @Override
    public List<ItemApplication> getItemInfoList(MonitorParamContext context) throws Exception {
        List<ItemApplication> itemApplications = new ArrayList<>();
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        QueryArgumentsParam monitorParam = (QueryArgumentsParam) context.getParam();
        boolean emptyDiscoverId = false;
        Map<String, Object> filter = new HashMap();
        if (Strings.isNullOrEmpty(monitorParam.getChartType())) {
            monitorParam.setChartType(line.getItemName());
        }
        ChartTypeEnum chartTypeEnum = getChartEnumByName(monitorParam.getChartType());
        //饼状图、top5暂时显示磁盘信息
        switch (chartTypeEnum) {
            case pie:
            case top5:
                filter.put(NAME_KEY, MW_DISK_UTILIZATION);
                break;
        }
        int serverId = 0;
        List<String> templateIds = new ArrayList<>();
        String hostId = "";
        List<String> discoveryIds = new ArrayList<>();
        if (monitorParam != null) {
            serverId = monitorParam.getMonitorServerId();
            hostId = monitorParam.getHostId();
            templateIds = monitorParam.getTemplateIds();
            discoveryIds = monitorParam.getDiscoveryIds();
            //是否数字
            if (chartTypeEnum.getFigureFlag()!=null && chartTypeEnum.getFigureFlag()) {
                filter.put(VALUE_TYPE_KEY, Arrays.asList("0", "3"));
                filter.put(VALUEMAPID_KEY, "0");
            }if (chartTypeEnum.getFigureFlag()!=null && !chartTypeEnum.getFigureFlag()) {
                filter.put(VALUE_TYPE_KEY, Arrays.asList("2", "4"));
                filter.put(VALUEMAPID_KEY, "0");
            }
            //是否百分比数据
            String units = chartTypeEnum.isPercentFlag() ? "%" : null;
            ItemApplication item = monitorParam.getItemApplication();
            if (null != item) {//添加查询监控项的筛选条件
                //如果不为空，说明是用户选择完一个以后的再选
                if (!chartTypeEnum.isMultipleFlag()) {//当多选是false时，说明是单选，后端直接返回空数组，控制前端为单选
                    return itemApplications;
                }
                if (!Strings.isNullOrEmpty(item.getDelay()) && chartTypeEnum.isFigureFlag()) {
                    filter.put(DELAY_KEY, item.getDelay());
                }
                if (!Strings.isNullOrEmpty(item.getUnits())) {
                    filter.put(UNITS_KEY, item.getUnits());
                }
                if (Strings.isNullOrEmpty(item.getDiscoverId())) {
                    emptyDiscoverId = true;
                } else {
                    List<ItemApplication> itemInfoByDiscoveryId = getItemInfoByDiscoveryId(zabbixDubboService, serverId, filter, Arrays.asList(item.getDiscoverId()));
                    itemApplications.addAll(itemInfoByDiscoveryId);
                    getItemChName(itemApplications, context);
                    return itemApplications;
                }
            } else if (!Strings.isNullOrEmpty(units)) {
                filter.put(UNITS_KEY, units);
            }
        }
        if (chartTypeEnum.isWithoutUnitsFlag()) {
            filter.remove(UNITS_KEY);
        }
        templateIds.add(hostId);
        if (serverId != 0 && CollectionUtils.isNotEmpty(templateIds)) {
            //根据模板获取监控项数据
            MWZabbixAPIResult itemsByTemplateIds = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_ITEMS_BY_TEMPLATE_IDS_FILTER, serverId, templateIds, filter,monitorParam.isMonitored());
            if (itemsByTemplateIds != null && itemsByTemplateIds.getData() != null) {
                itemApplications = JSONArray.parseArray(String.valueOf(itemsByTemplateIds.getData()), ItemApplication.class);
                Set<String> collect = itemApplications.stream().filter(s -> !Strings.isNullOrEmpty(s.getName())).map(s -> s.getName()).collect(Collectors.toSet());
                //根据自动发现规则id获取监控项数据
                if (!emptyDiscoverId) {
                    List<ItemApplication> itemInfoByDiscoveryId = getItemInfoByDiscoveryId(zabbixDubboService, serverId, filter, discoveryIds);
                    for(ItemApplication itemApplication : itemInfoByDiscoveryId){
                        if(!collect.contains(itemApplication.getName())){
                            itemApplications.add(itemApplication);
                        }

                    }
                }
            }
            getItemChName(itemApplications, context);
        }
        return itemApplications;
    }

    /**
     * item监控项获取中文描述
     *
     * @param itemApplications
     * @param context
     * @throws Exception
     */
    private void getItemChName(List<ItemApplication> itemApplications, MonitorParamContext context) throws Exception {
        if (CollectionUtils.isNotEmpty(itemApplications)) {
            ZabbixUtils zabbixUtils = SpringUtils.getBean(ZabbixUtils.class);
            List<String> itemName = zabbixUtils.itemNameSubStrConvert(itemApplications);
            ItemNameMapperInfo param = new ItemNameMapperInfo();
            param.setItemList(itemName);
            List<ItemNameMapperInfo> itemNameMapperList = getItemNameMapperList(param);
            Map<String, String> itemNameMap = itemNameMapperList.stream().filter(s -> !Strings.isNullOrEmpty(s.getItem())).collect(Collectors.toMap(s -> s.getItem(), s -> s.getDescrCn(), (
                    value1, value2) -> {
                return value2;
            }));
            for (ItemApplication itemApplication : itemApplications) {
                String chName = zabbixUtils.getChNameByMap(itemApplication.getName(), itemNameMap);
                itemApplication.setChName(chName);
            }
        }
    }

    /**
     * 获取模板所有自动发现规则中的监控项
     *
     * @return
     */
    public List<ItemApplication> getItemInfoByDiscoveryId(ZabbixDubboService zabbixDubboService, int serverId, Map<String, Object> filter, List<String> ruleIds) {
        List<ItemApplication> list = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(ruleIds)) {
            MWZabbixAPIResult itemPrototype = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_ITEM_BY_DISCOVERY_IDS, serverId, ruleIds, filter);
            if (itemPrototype != null) {
                List<ItemApplication> items = JSONArray.parseArray(String.valueOf(itemPrototype.getData()), ItemApplication.class);
                if (items != null && items.size() > 0) {
                    items.forEach(item -> {
                        if (item.getName().indexOf("[") != -1) {
                            item.setName(item.getName().substring(item.getName().indexOf("]") + 1));
                        }
                        item.setDiscoverId(item.getDiscoveryRule().getItemid());
                    });
                    list.addAll(items);
                }
            }

        }
        return list;
    }

    /**
     * 获取监控主机所有模板信息
     *
     * @param context
     */
    @Override
    public List<MwKeyValueParam> getAllTemplateInfoByHostId(MonitorParamContext context) {
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        QueryMonitorValue monitorParam = context.getQueryMonitorParam();
        List<String> templateIdList = new ArrayList<>();
        List<MwKeyValueParam> templateList = new ArrayList<>();
        if (monitorParam != null) {
            List<String> hostIds = monitorParam.getHostIds();
            int serverId = monitorParam.getMonitorServerId();
            MWZabbixAPIResult templatesResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_HOST_INFOS_BY_ID, serverId, hostIds);
            if (templatesResult != null && templatesResult.getData() != null) {
                List<MwZabbixHostResultParam> mwZabbixHostResultParams = JSONArray.parseArray(String.valueOf(templatesResult.getData()), MwZabbixHostResultParam.class);
                if (CollectionUtils.isNotEmpty(mwZabbixHostResultParams)) {
                    MwZabbixHostResultParam resultParam = mwZabbixHostResultParams.get(0);
                    List<MwZabbixTemplateResultParam> parentTemplates = resultParam.getParentTemplates();
                    //根据接口Api获取templateId
                    for (MwZabbixTemplateResultParam tempNode : parentTemplates) {
                        MwKeyValueParam valueParam = new MwKeyValueParam();
                        String templateId = tempNode.getTemplateid();
                        String templateName = tempNode.getName();
                        if (!Strings.isNullOrEmpty(templateId)) {
                            templateIdList.add(templateId);
                            valueParam.setValue(templateId);
                            valueParam.setName(templateName);
                            templateList.add(valueParam);
                        }
                    }
                }
            }
        }
        return templateList;
    }

    /**
     * 获取历史监控数据，前60条
     *
     * @param context
     * @return
     */
    @Override
    public MWZabbixAPIResult historyGetByItemid(MonitorParamContext context) {
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        QueryMonitorValue param = context.getQueryMonitorParam();
        List<String> itemIds = param.getItemIds();
        int type = 0;
        if (context.getParam() != null && context.getParam() instanceof Integer) {
            type = (Integer) context.getParam();
        }
        MWZabbixAPIResult mwZabbixAPIResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.HISTORY_GET_BY_ITEM_IDS, param.getMonitorServerId(), itemIds, type, limit);
        return mwZabbixAPIResult;
    }


    /**
     * 获取监控主机自动发现规则id
     *
     * @param context
     */
    @Override
    public List<String> getDiscoveryIdByHostId(MonitorParamContext context) {
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        QueryMonitorValue monitorParam = context.getQueryMonitorParam();
        MWZabbixAPIResult ruleByHostId = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_DRULE_BY_HOST_ID, monitorParam.getMonitorServerId(), monitorParam.getHostId());
        List<String> ruleIds = new ArrayList<>();
        if (ruleByHostId != null && !ruleByHostId.isFail() && ruleByHostId.getData()!=null) {
            log.info("getDiscoveryIdByHostId::"+ruleByHostId.getData());
            List<DiscoveryRuleParam> discoveryRuleParams = JSONArray.parseArray(String.valueOf(ruleByHostId.getData()), DiscoveryRuleParam.class);
            ruleIds = discoveryRuleParams.stream().map(s -> s.getItemid()).collect(Collectors.toList());
        }
        return ruleIds;
    }


    @Override
    public MonitorGroupInfoList getGroupInfo(MonitorParamContext context) {
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        //获取所有的主机分组信息
        MWZabbixAPIResult result = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.HOST_GROUP_GET, mwTPServerTable.getId(), null, true);
        log.info("hostGroupGet::" + result);
        if (result != null && !result.isFail()) {
            String info = "{\"groupInfoList\":" + String.valueOf(result.getData()) + "}";
            log.info("groupInfoList::" + info);
            MonitorGroupInfoList groupInfoList = com.alibaba.fastjson.JSONArray.parseObject(info, MonitorGroupInfoList.class);
            MonitorGroupInfoList ret = new MonitorGroupInfoList();
            List<MonitorGroupInfo> monitorGroupInfos = new ArrayList<>();
            ret.setGroupInfoList(monitorGroupInfos);

            //在监控服务中可能含有前缀需要去掉
            if (StringUtils.hasText(groupPrefix)) {
                if (null != groupInfoList.getGroupInfoList()) {
                    for (MonitorGroupInfo monitorGroupInfo : groupInfoList.getGroupInfoList()) {
                        int index = monitorGroupInfo.getName().indexOf(groupPrefix);
                        if (index >= 0) {
                            String newName = monitorGroupInfo.getName().substring(index + groupPrefix.length());
                            monitorGroupInfo.setName(newName);
                            monitorGroupInfos.add(monitorGroupInfo);
                        }
                    }
                }
            }
            return ret;
        }
        return null;
    }

    @Override
    public MonitorGroupInfoList createGroupInfo(MonitorParamContext context) throws Exception {
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        List<String> groupNameList = context.getGroupNameList();
        List<Map> groupInfoMap = new ArrayList<>();
        for (String groupName : groupNameList) {
            Map<String, String> m = new HashMap<>();
            m.put(NAME_KEY, groupPrefix + groupName);
            groupInfoMap.add(m);
        }
        MWZabbixAPIResult mwZabbixAPIResult2 = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.BATCH_CREATE_HOST_GROUP, mwTPServerTable.getId(), groupInfoMap);
        MonitorGroupInfoList ret = new MonitorGroupInfoList();
        List<MonitorGroupInfo> monitorGroupInfos = new ArrayList<>();
        ret.setGroupInfoList(monitorGroupInfos);
        if (mwZabbixAPIResult2 != null && !mwZabbixAPIResult2.isFail()) {
            JSONObject node = JSONObject.parseObject(JSON.toJSONString(mwZabbixAPIResult2.getData()));
            if (node.size() > 0) {
                JSONArray groupids = (JSONArray) node.get(GROUP_IDS);
                for (int x = 0; x < groupids.size(); x++) {
                    MonitorGroupInfo monitorGroupInfo = new MonitorGroupInfo();
                    String groupid = groupids.get(x).toString();
                    monitorGroupInfo.setGroupid(groupid);
                    monitorGroupInfo.setName(groupNameList.get(x));
                    monitorGroupInfo.setServerId(mwTPServerTable.getId());
                    monitorGroupInfos.add(monitorGroupInfo);
                }
            } else {
                throw new CreateMonitorGroupException();
            }
        } else {
            throw new CreateMonitorGroupException();
        }
        return ret;

    }

    /**
     * 新增修改监控itemName映射数据
     */
    @Override
    public void addAndUpdateItemNameMapper(MonitorParamContext context) throws Exception {
        ItemNameMapper itemNameMapper = (ItemNameMapper) context.getBaseMapper();
        ItemNameMapperInfo param = (ItemNameMapperInfo) context.getParam();
        ItemNameParam itemNameParam = itemNameFilterBracket(param.getItem());
        String itemName = itemNameParam.getItemName();
        Query query = new Query();
        List<Criteria> criteriaList = new ArrayList<>();
        criteriaList.add(CriteriaWrapper.where(ItemNameMapperInfo::getZabbixItem).is(itemName));
        criteriaList.add(CriteriaWrapper.where(ItemNameMapperInfo::getDescrCn).is(param.getDescrCn()));
        query.addCriteria(new Criteria().orOperator(criteriaList));
        Update update = new Update();
        update.set(CMDBTool.getFieldName(ItemNameMapperInfo::getZabbixItem), itemName);
        update.set(CMDBTool.getFieldName(ItemNameMapperInfo::getDescrCn), param.getDescrCn());
        itemNameMapper.upsert(query, update);
    }

    /**
     * 获取item监控历史数据
     *
     * @return
     */
    @Override
    public List<MWItemHistoryDTO> getMonitorHistoryData(MonitorParamContext context) {
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        QueryItemHistoryParam param = (QueryItemHistoryParam) context.getParam();
        int serverId = param.getMonitorServerId();
        List<String> itemIds = param.getItemIds();
        Long timeFrom = param.getStartDate();
        Long timeTill = param.getEndDate();
        Integer type = param.getValueType();
        int dateType = param.getDateType();
        List<MWItemHistoryDTO> mwItemHistoryDTOS = HistoryGetByTimeAndHistory(zabbixDubboService, serverId, itemIds, timeFrom, timeTill, type, dateType);

//        MWZabbixAPIResult zabbixAPIResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.HistoryGetByTimeAndTypeASC(serverId, itemIds, timeFrom, timeTill, type);
//        List<MWItemHistoryDTO> list = new ArrayList<>();
//        if (zabbixAPIResult != null && zabbixAPIResult.getCode() == 0) {
//            JsonNode resultData = (JsonNode) zabbixAPIResult.getData();
//            if (resultData.size() > 0) {
//                list = JSONArray.parseArray(String.valueOf(resultData), MWItemHistoryDTO.class);
//            }
//        }
        return mwItemHistoryDTOS;
    }


    public List<MWItemHistoryDTO> HistoryGetByTimeAndHistory(ZabbixDubboService zabbixDubboService, int serverId, List<String> itemids, long time_from, long time_till, Integer type, Integer DataType) {
        long time1 = System.currentTimeMillis();
        Date date = new Date();
        List<Long> timeList = new ArrayList<>();
        List<String> strList = new ArrayList<>();
        //时间类型为一周
        if (DataType == 3) {

            for (int i = 0; i <= 7; i++) {
                long time = DateUtils.addDays(date, (-i + 1)).getTime() / 1000;
                String date1 = DateUtils.formatDate(DateUtils.addDays(date, (-i + 1)));
                timeList.add(time);
                strList.add(date1);
            }
        }//时间类型为一个月
        else if (DataType == 4) {
            for (int i = 0; i <= 10; i++) {
                long time = DateUtils.addDays(date, (-(i)* 3)).getTime() / 1000;
                String date1 = DateUtils.formatDate(DateUtils.addDays(date, (-(i)* 3)));
                timeList.add(time);
                strList.add(date1);
            }
        } else {
            timeList.add(time_till);
            timeList.add(time_from);
        }
        int coreSizePool = Runtime.getRuntime().availableProcessors() * 2 + 1;
        logger.info("历史数据折线图线程数coreSizePool：" + coreSizePool);
        ThreadPoolExecutor executorService = new ThreadPoolExecutor(timeList.size(), timeList.size() + 2, 10, TimeUnit.MINUTES, new LinkedBlockingQueue<>());
        List<Future<MWZabbixAPIResult>> futureList = new ArrayList<>();
        List<MWZabbixAPIResult> lists = new ArrayList<>();
        Integer serverIds = serverId;
        List<String> itemidList = itemids;
        Integer types = type;
        for (int y = 0, len = timeList.size(); y < len - 1; y++) {
            long timeStrat = timeList.get(y + 1);
            long timeEnd = timeList.get(y);

            Callable<MWZabbixAPIResult> callable = new Callable<MWZabbixAPIResult>() {
                @Override
                public MWZabbixAPIResult call() throws Exception {
                    log.info("多线程:" + Thread.currentThread().getName() + "开始");
                    MWZabbixAPIResult mwZabbixAPIResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.HISTORY_GET_BY_TIME_AND_TYPE_ASC, serverIds, itemidList, timeStrat, timeEnd, types);
                    return mwZabbixAPIResult;
                }
            };
            ////System.out.println("多线程存值："+System.currentTimeMillis()+"ms");
            Future<MWZabbixAPIResult> submit = executorService.submit(callable);
            futureList.add(submit);
        }
        if (futureList.size() > 0) {
            futureList.forEach(f -> {
                try {
                    MWZabbixAPIResult result = f.get(200, TimeUnit.SECONDS);
                    lists.add(result);
                } catch (Exception e) {
                    log.error("fail to HistoryGetByTimeAndHistory with", e);
                }
            });
        }
        executorService.shutdown();
        logger.info("关闭线程池");
        long time2 = System.currentTimeMillis();
        List<MWItemHistoryDTO> list = new ArrayList<>();

        for (MWZabbixAPIResult mwZabbixAPIResult1 : lists) {

            if (mwZabbixAPIResult1 != null && mwZabbixAPIResult1.getCode() == 0) {
                if (mwZabbixAPIResult1.getData() != null) {
                    list.addAll(JSONArray.parseArray(JSON.toJSONString(mwZabbixAPIResult1.getData()), MWItemHistoryDTO.class));
                }
            }
        }

        long time3 = System.currentTimeMillis();
        ////System.out.println("zabbix服务获取数据耗时：" + (time2 - time1) + "ms" + "数据整理：" + (time3 - time2) + "ms" + "");
        List<MWItemHistoryDTO> listSort = new ArrayList<>();
        listSort = list.stream().filter(item -> item.getClock() != null).sorted(Comparator.comparing(MWItemHistoryDTO::getClock)).collect(Collectors.toList());
        logger.info("总耗时：" + (time3 - time1) + "ms");
        return listSort;
    }


    @Override
    public boolean itemCheckNow(MonitorParamContext context) {
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        QueryMonitorParam param = (QueryMonitorParam) context.getParam();
        //将所有的监控项进行是否立即执行 "6"是立即执行；"1"是诊断信息
        MWZabbixAPIResult result = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.TASK_ITEMS, param.getMonitorServerId(), itemCheckNowCode, param.getItemIds());
        if (result != null && !result.isFail()) {
            if (result.getData() != null && result.getData() != null) {
                MwItemCheckNowParam itemCheckNowParam = JSONObject.parseObject(JSON.toJSONString(result.getData()), MwItemCheckNowParam.class);
                if (itemCheckNowParam.getTaskids() != null && itemCheckNowParam.getTaskids().size() > 0) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 获取item监控历史数据
     *
     * @return
     */
    @Override
    public MWZabbixAPIResult queryItemInfos(MonitorParamContext context) {
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        QueryItemInfoListParam param = (QueryItemInfoListParam) context.getParam();
        int serverId = param.getMonitorServerId();
        List<String> hostIds = param.getHostIds();
        List<String> itemNames = param.getItemNames();
        MWZabbixAPIResult itemInfosList = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.ITEM_GET_BY_HOST_IDS_SEARCH, serverId, itemNames, hostIds);
        return itemInfosList;
    }


    /**
     * 获取趋势数据
     *
     * @param context
     * @return
     */
    @Override
    public List<MWItemHistoryDTO> getMonitorTrendData(MonitorParamContext context) {
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        QueryItemHistoryParam param = (QueryItemHistoryParam) context.getParam();
        int serverId = param.getMonitorServerId();
        List<String> itemIds = param.getItemIds();
        Long timeFrom = param.getStartDate();
        Long timeTill = param.getEndDate();
        MWZabbixAPIResult zabbixAPIResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.TREND_BATCH_GET, serverId, itemIds, timeFrom, timeTill);
        List<MWItemHistoryDTO> list = new ArrayList<>();
        if (zabbixAPIResult != null && zabbixAPIResult.getCode() == 0) {
            if (zabbixAPIResult.getData() != null) {
                list = JSONArray.parseArray(JSON.toJSONString(zabbixAPIResult.getData()), MWItemHistoryDTO.class);
            }
        }
        return list;
    }


    /**
     * 获取主机运行时长和cpu内存大小
     *
     * @param context
     * @return
     */
    @Override
    public HostDetailDto getUptimeAndCpuMemoryInfo(MonitorParamContext context) {
        HostDetailDto hostDetailDto = new HostDetailDto();
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        QueryMonitorParam queryParam = (QueryMonitorParam) context.getParam();
        int serverId = 0;
        String hostId = "";
        if (queryParam != null) {
            serverId = queryParam.getMonitorServerId();
            hostId = queryParam.getHostId();
            long lastvalue = 0;
            String longTime = "";
            //获取主机运行时间
            MWZabbixAPIResult uptimeResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.ITEM_GET_BY_KEY, serverId, hostId, SYSTEM_UPTIME.getItemName());
            if (uptimeResult != null && !uptimeResult.isFail()) {
                List<MwZabbixItemResultParam> uptimeResultList = JSONArray.parseArray(JSON.toJSONString(uptimeResult.getData()), MwZabbixItemResultParam.class);

                if (CollectionUtils.isNotEmpty(uptimeResultList)) {
                    lastvalue = longValueConvert(uptimeResultList.get(0).getLastvalue());
                }
            }
            if (lastvalue != 0) {
                longTime = SeverityUtils.getLastTime(lastvalue);
            }
            hostDetailDto.setRunTime(longTime);
            MWZabbixAPIResult result = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.ITEM_GET_BY_NAME_LIST, serverId, Arrays.asList(ZabbixItemEnum.CPU_CORE.getItemName(), ZabbixItemEnum.MEMORY_TOTAL.getItemName()), hostId, true);
            if (result != null && !result.isFail()) {
                List<MwZabbixItemResultParam> resultList = JSONArray.parseArray(JSON.toJSONString(result.getData()), MwZabbixItemResultParam.class);

                if (CollectionUtils.isNotEmpty(resultList)) {
                    for (MwZabbixItemResultParam resultParam : resultList) {
                        String name = resultParam.getName();
                        if (ZabbixItemEnum.CPU_CORE.getItemName().equals(name)) {
                            hostDetailDto.setCPUCores(intValueConvert(resultParam.getLastvalue()));
                        }
                        if (ZabbixItemEnum.MEMORY_TOTAL.getItemName().equals(name)) {
                            hostDetailDto.setTotalMemory(UnitUtil.getValueWithUnits(strValueConvert(resultParam.getLastvalue()), resultParam.getUnits()));
                        }
                    }
                }
            }

        }
        return hostDetailDto;
    }

    @Override
    public void batchEditorProxyValue(MonitorParamContext context) {
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        QueryMonitorParam queryMonitorParam = (QueryMonitorParam) context.getQueryMonitorParam();

        if (queryMonitorParam != null) {
            Integer serverId = queryMonitorParam.getMonitorServerId();
            List<String> hostIds = queryMonitorParam.getHostIds();
            String proxyId = queryMonitorParam.getMwProxyId();
            Integer proxyType = queryMonitorParam.getMwProxyType();
            Map<String, Object> updateParam = new HashMap<>();
            if (proxyType != null && proxyType.intValue() > 0) {
                //如果轮询引擎为空，设置本机监控
                if(Strings.isNullOrEmpty(proxyId)){
                    updateParam.put("monitored_by", 0);
                }else{
                    if (proxyType.intValue() == 2) {
                        updateParam.put("monitored_by", 2);
                        updateParam.put("proxy_groupid", proxyId);
                    } else {
                        updateParam.put("monitored_by", 1);
                        updateParam.put("proxyid", proxyId);
                    }
                }
            } else {
                updateParam.put("proxy_hostid", proxyId);
            }
            log.info("HOST_BATCH_UPDATE::"+strValueConvert(updateParam));
            zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.HOST_BATCH_UPDATE, serverId, hostIds, updateParam);
        }
    }


    /**
     * 根据itemName获取ItemId信息
     *
     * @param context
     * @return
     */
    @Override
    public List<MwZabbixItemResultParam> getItemIdByName(MonitorParamContext context) {
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        List<String> itemNameList = context.getItemNameList();
        QueryMonitorParam queryParam = (QueryMonitorParam) context.getParam();
        List<MwZabbixItemResultParam> resultList = new ArrayList<>();

        MWZabbixAPIResult result = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.ITEM_GET_BY_NAME_LIST, queryParam.getMonitorServerId(), itemNameList, queryParam.getHostId(), true);
        if (result != null && !result.isFail()) {
            resultList = JSONArray.parseArray(JSON.toJSONString(result.getData()), MwZabbixItemResultParam.class);
        }
        return resultList;
    }

    /**
     * 获取资产可运行历史数据
     */
    @Override
    public List<MWItemHistoryDTO> getAvailableByItemId(MonitorParamContext context) {
        QueryItemHistoryParam param = (QueryItemHistoryParam) context.getParam();
        List<MWItemHistoryDTO> historyDTOList = new ArrayList<>();
        long time11 = System.currentTimeMillis();
        //时间小于三天，从历史数据中获取，大于三天，从趋势数据中获取
        long day = (param.getEndDate() - param.getStartDate()) / (86400);
        if (day <= 3) {
            List<MWItemHistoryDTO> historyDtos = getMonitorHistoryData(context);
            historyDTOList.addAll(historyDtos);
        } else {
            List<MWItemHistoryDTO> listInfo = getAssetsTrendInfo(context);
            //趋势数据为空时，从历史数据中取值
            if (CollectionUtils.isEmpty(listInfo)) {
                listInfo = getMonitorHistoryData(context);
            }
            historyDTOList.addAll(listInfo);
        }
        long time12 = System.currentTimeMillis();
        log.info("获取资产可用性查询耗时：" + (time12 - time11) + "ms;");
        return historyDTOList;
    }

    /**
     * 获取趋势数据
     *
     * @param context
     */
    public List<MWItemHistoryDTO> getAssetsTrendInfo(MonitorParamContext context) {
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        QueryItemHistoryParam param = (QueryItemHistoryParam) context.getParam();
        Long startTime = param.getStartDate();
        Long endTime = param.getEndDate();
        int serverId = param.getMonitorServerId();
        List<String> itemIds = param.getItemIds();
        List<MWItemHistoryDTO> historyDtoToDay = new ArrayList<>();
        if (startTime == null || endTime == null || serverId == 0 || CollectionUtils.isEmpty(itemIds)) {
            return historyDtoToDay;
        }
        //查询趋势数据
        MWZabbixAPIResult mwZabbixAPIResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.TREND_BATCH_GET, serverId, itemIds, startTime, endTime);
        log.info("资产可用性取趋势数据" + mwZabbixAPIResult);
        if (mwZabbixAPIResult == null || mwZabbixAPIResult.isFail()) {
            return historyDtoToDay;
        }
        List<MWItemHistoryDTO> list = new ArrayList<>();
        if (mwZabbixAPIResult.getData() != null) {
            list = JSONArray.parseArray(JSON.toJSONString(mwZabbixAPIResult.getData()), MWItemHistoryDTO.class);
        }
        return list;
    }

    /**
     * 根据饼状图有关信息：总量，已使用，未使用
     *
     * @return
     */
    @Override
    public List<ItemTotalInfoParam> getItemTotalInfo(MonitorParamContext context) throws Exception {
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        MwMonitorHistoryParam param = (MwMonitorHistoryParam) context.getParam();
        int monitorServerId = param.getMonitorServerId();
        List<String> names = param.getInterfaceDrops();
        String hostId = param.getHostId();
        List<String> nameList = new ArrayList<>();
        List<String> itemNames = param.getItemNamesDropInfos();
        List<String> allItemIds = param.getItemIdsDropInfos();
        String nameDev = "";
        String chartType = param.getChartType();
        ChartTypeEnum chartEnum = ChartTypeEnum.getChartEnumByName(chartType);
        boolean isPie = false;
        //饼状图暂时显示磁盘信息
        switch (chartEnum) {
            case pie:
                isPie = true;
                break;
        }
        for (String item : itemNames) {
            if (CollectionUtils.isNotEmpty(names)) {
                for (String str : names) {
                    String prefixName = isPie ? itemPrefix : item;
                    nameList.add(str + prefixName);
                }
            } else {
                nameList = itemNames;
            }
        }
        //查询item对应的中文描述
        ItemNameMapperInfo itemParam = new ItemNameMapperInfo();
        itemParam.setItemList(itemNames);
        List<ItemNameMapperInfo> itemNameMapperList = getItemNameMapperList(itemParam);
        Map<String, String> itemNameMap = itemNameMapperList.stream().filter(s -> !Strings.isNullOrEmpty(s.getItem())).collect(Collectors.toMap(s -> s.getItem(), s -> s.getDescrCn()));

        List<ItemTotalInfoParam> list = new ArrayList<>();
        MWZabbixAPIResult result1 = new MWZabbixAPIResult();
        if (isPie) {//磁盘利用率饼状图需要根据名称模糊查询相关数据（磁盘总量，剩余量等）
            result1 = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.ITEM_GET_BY_TYPE, monitorServerId, nameList, hostId, false);
        } else {//其他类型直接根据itemId查询
            result1 = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.ITEM_GET_BY_ITEM_ID_LIST, monitorServerId, allItemIds);
        }
        if (result1 != null && result1.getCode() == 0) {
            if (result1.getData() != null) {
                List<MwZabbixItemResultParam> itemResult = JSONArray.parseArray(JSON.toJSONString(result1.getData()), MwZabbixItemResultParam.class);
                Map<String, MwZabbixItemResultParam> collect = itemResult.stream().collect(Collectors.toMap(s -> s.getName(), s -> s));
                for (String item : itemNames) {
                    if (CollectionUtils.isNotEmpty(names)) {//有监控项接口信息，[]里存在数据
                        for (String name : names) {
                            ItemTotalInfoParam diskListDto = new ItemTotalInfoParam();
                            if (!CollectionUtils.isMapEmpty(collect)) {
                                diskListDto.setType(name);
                                diskListDto.setItemName(itemNameMap.get(item));
                                if (itemNameMap != null && itemNameMap.containsKey(item)) {
                                    diskListDto.setItemName(itemNameMap.get(item));
                                }
                                String newName = name + "MW_";
                                String s = name + item;
                                commonMatch(newName, s, collect, diskListDto);
                            }
                            list.add(diskListDto);
                        }
                    } else {//没有监控项接口信息，，[]不存在
                        ItemTotalInfoParam diskListDto = new ItemTotalInfoParam();
                        if (!CollectionUtils.isMapEmpty(collect)) {
                            diskListDto.setItemName(item);
                            if (itemNameMap != null && itemNameMap.containsKey(item)) {
                                diskListDto.setItemName(itemNameMap.get(item));
                            }
                            String newName = "MW_";
                            String s = item;
                            commonMatch(newName, s, collect, diskListDto);
                        }
                        list.add(diskListDto);
                    }

                }
            }
        }
        return list;
    }

    private void commonMatch(String newName, String s, Map<String, MwZabbixItemResultParam> collect, ItemTotalInfoParam diskListDto) {
        MwZabbixItemResultParam itemResultParam = new MwZabbixItemResultParam();
        if (collect.containsKey(s)) {
            itemResultParam = collect.get(s);
            UnitResult valueConvert = getValueConvert(itemResultParam);
            diskListDto.setLastValue(valueConvert.getValue());
            diskListDto.setUnit(valueConvert.getUnits());
            diskListDto.setValuemapid(itemResultParam.getValuemapid());
        }
        if (collect.containsKey(newName + DISK_USED)) {
            itemResultParam = collect.get(newName + DISK_USED);
            UnitResult valueConvert = getValueConvert(itemResultParam);
            diskListDto.setUsed(valueConvert.getResult());
        }
        if (collect.containsKey(newName + DISK_FREE)) {
            itemResultParam = collect.get(newName + DISK_FREE);
            UnitResult valueConvert = getValueConvert(itemResultParam);
            diskListDto.setFree(valueConvert.getResult());
        }
        if (collect.containsKey(newName + DISK_TOTAL)) {
            itemResultParam = collect.get(newName + DISK_TOTAL);
            UnitResult valueConvert = getValueConvert(itemResultParam);
            diskListDto.setTotal(valueConvert.getResult());
        }
        diskListDto.setLastUpdateTime(itemResultParam.getDateConvert());
    }

    private UnitResult getValueConvert(MwZabbixItemResultParam itemResultParam) {
        String lastValue = strValueConvert(itemResultParam.getLastvalue());
        String units = itemResultParam.getUnits();
        UnitResult unitResult = UnitUtil.getValueAndUnits(lastValue, units);
        return unitResult;
    }

    @Override
    public List getNames(MonitorParamContext context) {
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        MwMonitorHistoryParam param = (MwMonitorHistoryParam) context.getParam();
        int monitorServerId = param.getMonitorServerId();
        Set<String> listName = new HashSet<>();
        List<ItemNameParam> nameList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(param.getItemIdsDropInfos())) {
            MWZabbixAPIResult result = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_ITEM_NAME, monitorServerId, param.getItemIdsDropInfos());
            if (result != null && result.getCode() == 0) {
                List<MwZabbixItemResultParam> itemResultList = JSONArray.parseArray(JSON.toJSONString(result.getData()), MwZabbixItemResultParam.class);
                for (MwZabbixItemResultParam itemResult : itemResultList) {
                    ItemNameParam itemParam = new ItemNameParam();
                    String name = itemResult.getName();
                    if (name.indexOf("[") != -1) {
                        ItemNameParam itemNameParam = itemNameFilterBracket(name);
                        String itemid = itemResult.getItemid();
                        itemParam.setDevName(itemNameParam.getDevName());
                        itemParam.setItemName(itemNameParam.getItemName());
                        itemParam.setItemId(itemid);
                        nameList.add(itemParam);
                    }
                }
                for (MwZabbixItemResultParam resultParam : itemResultList) {
                    String name = resultParam.getName();
                    if (name.indexOf("[") != -1) {
                        name = name.substring(name.indexOf("[") + 1, name.indexOf("]"));
                        listName.add(name);
                    }
                }
            }
        }
        List<String> names = new ArrayList<>(listName);
        List<String> sortedNames = names.stream().sorted().collect(Collectors.toList());
        return nameList;
    }

    /**
     * 获取监控itemName映射数据
     *
     * @param param
     * @return
     * @throws Exception
     */
    @Override
    public List<ItemNameMapperInfo> getItemNameMapperList(ItemNameMapperInfo param) throws Exception {
        ItemNameMapper itemNameMapper = SpringUtils.getBean(ItemNameMapper.class);
        List<ItemNameMapperInfo> objects = new ArrayList<>();
        if (param != null && CollectionUtils.isNotEmpty(param.getItemList())) {
            Query query = new Query(CriteriaWrapper.where(ItemNameMapperInfo::getZabbixItem).in(param.getItemList()));
            objects = itemNameMapper.find(query);
        } else {
            Query query = new Query(CriteriaWrapper.where(ItemNameMapperInfo::getZabbixItem).ne(null).ne(""));
            objects = itemNameMapper.find(query);
        }
        for (ItemNameMapperInfo itemInfo : objects) {
            itemInfo.setItem(itemInfo.getZabbixItem());
        }
        //如果数据库查询不到数据
        if (CollectionUtils.isEmpty(objects) && CollectionUtils.isNotEmpty(param.getItemList())) {
            for (String item : param.getItemList()) {
                ItemNameMapperInfo itemNameMapperInfo = new ItemNameMapperInfo();
                itemNameMapperInfo.setItem(item);
                itemNameMapperInfo.setDescrCn(item);
                objects.add(itemNameMapperInfo);
            }
        }
        return objects;
    }


    /**
     * 获取高级表格应用集
     *
     * @param context
     * @return
     */
    @Override
    public List<ApplicationDTO> getApplication(MonitorParamContext context) {
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        QueryMonitorParam param = (QueryMonitorParam) context.getParam();
        MWZabbixAPIResult result = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_APPLICATION, param.getMonitorServerId(), param.getHostId());
        List<ApplicationDTO> applicationDTOS = new ArrayList<>();
        if (result != null && result.getCode() == 0) {
            applicationDTOS = zabbixDubboService.analysisResult(param.getMonitorServerId(), strValueConvert(result.getData()));
        }
        return applicationDTOS;
    }

    /**
     * 监控指标获取全部应用集
     *
     * @param context
     * @return
     */
    @Override
    public List<ApplicationDTO> getAllApplicationList(MonitorParamContext context) {
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        QueryMonitorParam param = (QueryMonitorParam) context.getQueryMonitorParam();

        log.info("getApplication 获取应用集，开始运行");
        List<ApplicationDTO> list = new ArrayList<>();
        List<ApplicationDTO> LLDList = new ArrayList<>();

        int monitorServerId = param.getMonitorServerId();
        List<String> hostIdList = param.getHostIds();
        List<List<String>> subList = Lists.partition(hostIdList, maxHostIdNum);
        if (CollectionUtils.isNotEmpty(subList)) {
            List<ApplicationDTO> listAll = new ArrayList<>();
            for (List<String> hostIds : subList) {
                if (CollectionUtils.isNotEmpty(hostIds)) {
                    MWZabbixAPIResult result = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_APPLICATION, param.getMonitorServerId(), hostIds);
                    List<ApplicationDTO> disList = new ArrayList<>();
                    if (result != null) {
                        disList = zabbixDubboService.analysisResult(param.getMonitorServerId(), String.valueOf(result.getData()));
                    }
                    listAll.addAll(disList);
                    MWZabbixAPIResult LLDResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_DRULE_BY_HOST_ID, monitorServerId, hostIds);
                    ApplicationDTO LLDDto = new ApplicationDTO();
                    LLDDto.setName(ZabbixItemConstant.APPLICATION_LLD);
                    LLDDto.setChName(ZabbixItemConstant.APPLICATION_LLD);
                    if (LLDResult != null && LLDResult.getCode() == 0) {
                        String data = String.valueOf(LLDResult.getData());
                        List<ApplicationDTO> all = JSONArray.parseArray(data, ApplicationDTO.class);
                        LLDDto.setCount(all.size());
                        LLDDto.setItemIds(all.stream().map(item -> item.getItemid()).collect(Collectors.toList()));
                    }
                    LLDList.add(LLDDto);
                }
            }
            //设置LLD数据
            ApplicationDTO LLDDto = new ApplicationDTO();
            LLDDto.setName(ZabbixItemConstant.APPLICATION_LLD);
            LLDDto.setChName("LLD");
            int LLDCount = LLDList.stream().filter(s -> s.getCount() != null).mapToInt(s -> s.getCount()).sum();
            List<String> LLDItemIds = LLDList.stream().filter(s -> s.getItemIds() != null).flatMap(item -> item.getItemIds().stream()).collect(Collectors.toList());
            LLDDto.setCount(LLDCount);
            LLDDto.setItemIds(LLDItemIds);
            //设置全部数据
            ApplicationDTO appDTO = new ApplicationDTO();
            appDTO.setName(ZabbixItemConstant.APPLICATION_NAME);
            appDTO.setChName(ZabbixItemConstant.APPLICATION_NAME);
            int count = listAll.stream().filter(s -> s.getCount() != null).mapToInt(s -> s.getCount()).sum();
            List<String> itemIds = listAll.stream().filter(s -> s.getItemIds() != null).flatMap(item -> item.getItemIds().stream()).collect(Collectors.toList());
            appDTO.setCount(count + LLDDto.getCount());
            appDTO.setItemIds(itemIds);
            list.addAll(listAll);
            list.add(appDTO);
            list.add(LLDDto);
        }
        List<ApplicationDTO> applicationDTOS = list;
        for (ApplicationDTO applicationDTO : applicationDTOS) {
            if (CollectionUtils.isNotEmpty(applicationDTO.getItems())) {
                applicationDTO.getItems().clear();
            }
        }
        return applicationDTOS;
    }

    /**
     * 虚拟化设备获取所关联设备主机id
     */
    @Override
    public List<String> getVcenterRelationAssetsHostId(MonitorParamContext context) {
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        QueryMonitorParam param = (QueryMonitorParam) context.getQueryMonitorParam();
        //判断是否是虚拟化设备
        List<String> hostIdList = new ArrayList<>();
        String ip = (String) context.getParam();
        if(param!=null){
            MWZabbixAPIResult hostInfoResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_HOST_INFO_BY_NAME, param.getMonitorServerId(), "<" + ip + ">");
            String hostId = "";
            if (hostInfoResult != null && hostInfoResult.getCode() == 0) {
                if (hostInfoResult.getData() != null) {
                    List<MwZabbixHostResultParam> itemResultList = JSONArray.parseArray(JSON.toJSONString(hostInfoResult.getData()), MwZabbixHostResultParam.class);
                    for (MwZabbixHostResultParam hostInfo : itemResultList) {
                        hostId = hostInfo.getHostid();
                        hostIdList.add(hostId);
                    }
                }
            }
        }
        return hostIdList;
    }


    @Override
    public MWZabbixAPIResult getItemNameByAppName(MonitorParamContext context) {
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        MwZabbixApplicationResultParam param = (MwZabbixApplicationResultParam) context.getParam();
        MWZabbixAPIResult result = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_ITEM_NAME_BY_APP_NAME, param.getMonitorServerId(), param.getHostId(), param.getApplicationName(), "");
        return result;
    }

    @Override
    public List<String> getItemIdsByAppName(MonitorParamContext context) {
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        List<MwZabbixItemResultParam> itemResultParams = new ArrayList<>();
                MwQueryApplicationParam param = (MwQueryApplicationParam) context.getParam();
        MWZabbixAPIResult result = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_ITEM_IDS_BY_APP_NAME, param.getMonitorServerId(), param.getHostId(), param.getApplicationName());
        if(result != null && result.getCode() == 0){
            itemResultParams = JSONArray.parseArray(String.valueOf(result.getData()), MwZabbixItemResultParam.class);
        }
        List<String> itemIds = new ArrayList<>();
        for (MwZabbixItemResultParam resultParam : itemResultParams) {
            itemIds.add(resultParam.getItemid());
        }
        return itemIds;
    }

    @Override
    public MWZabbixAPIResult getItemInfoByAppNameAndIds(MonitorParamContext context) {
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        MwQueryApplicationParam param = (MwQueryApplicationParam) context.getParam();
        MWZabbixAPIResult result = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_ITEM_INFO_BY_APP_NAME_AND_IDS, param.getMonitorServerId(), param.getHostId(), param.getApplicationName(), param.getItemIds());
        return result;
    }

    @Override
    public MWZabbixAPIResult getItemInfoByAppName(MonitorParamContext context) {
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        MwQueryApplicationParam param = (MwQueryApplicationParam) context.getParam();
        String applicationName = param.getApplicationName();
        MWZabbixAPIResult result = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_ITEM_DATA_BY_APP_NAME, param.getMonitorServerId(), param.getHostId(), applicationName, "");
        return result;
    }

    @Override
    public MWZabbixAPIResult getDRuleByHostId(MonitorParamContext context) {
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        MwQueryApplicationParam param = (MwQueryApplicationParam) context.getParam();
        MWZabbixAPIResult result = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_DRULE_BY_HOST_ID, param.getMonitorServerId(), param.getHostId());
        return result;
    }

    @Override
    public MWZabbixAPIResult getItemResultByItemName(MonitorParamContext context) {
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        QueryMonitorValue param = context.getQueryMonitorParam();
        ParamContext paramContext = (ParamContext) context.getParam();
        //监控项名称
        String itemName = strValueConvert(paramContext.getObj());
        List<String> itemNames = new ArrayList<>();
        List<String> devNames = paramContext.getDevNames();
        if (CollectionUtils.isNotEmpty(devNames)) {
            for (String devName : devNames) {
                itemNames.add(devName + itemName);
            }
        } else {
            itemNames.add(itemName);
        }

        MWZabbixAPIResult result = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_ITEM_DATA_BY_SEARCH_APP_NAME_AND_ITEM_NAMES, param.getMonitorServerId(), param.getHostId(), paramContext.getApplicationName(), itemNames);
        return result;
    }

    @Override
    public MWZabbixAPIResult getItemResultByApplicationName(MonitorParamContext context) {
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        QueryMonitorValue param = context.getQueryMonitorParam();
        ParamContext paramContext = (ParamContext) context.getParam();
        List<String> itemNames = paramContext.getItemNames();
        MWZabbixAPIResult result = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_ITEM_DATA_BY_APP_NAME_LIST, param.getMonitorServerId(), param.getHostIds(), paramContext.getApplicationName(), itemNames,true);
        return result;
    }



    @Override
    public void updateHostIpInfo(MonitorParamContext context) throws Exception {
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        QueryMonitorValue param = context.getQueryMonitorParam();
        Object ipObj = context.getParam();
        MWZabbixAPIResult result = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.HOST_INTERFACE_GET, param.getMonitorServerId(), param.getHostId());
        if (result!=null && !result.isFail()) {
            JsonNode jsonNode = (JsonNode) result.getData();
            if (jsonNode.size() > 0) {
                String interfaceid = jsonNode.get(0).get("interfaceid").asText();
                Map<String, Object> map = new HashMap<>();
                map.put("ip", ipObj);
                MWZabbixAPIResult updateResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.HOST_INTERFACE_UPDATE, param.getMonitorServerId(), interfaceid, map);
                if (updateResult != null && updateResult.isFail()) {
                    throw new WarnTitleException("update_host_ip");
                }
            }
        }
    }


    //根据item中valuemapid属性，转换成对应的value值
    @Override
    public List<ValuemapDto> getValueMapByIdList(MonitorParamContext context) {
        ZabbixDubboService zabbixDubboService = context.getZabbixDubboService();
        QueryMonitorValue param = context.getQueryMonitorParam();
        List<String> valuemapIds = new ArrayList<>();
        List<ValuemapDto> dataList = new ArrayList<>();

        if (context.getParam() != null && context.getParam() instanceof List) {
            valuemapIds = (List<String>) context.getParam();
            MWZabbixAPIResult valueMapById = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_VALUE_MAP_BY_ID, param.getMonitorServerId(), valuemapIds);
            if (null != valueMapById && valueMapById.getCode() == 0) {
                dataList = JSONArray.parseArray(String.valueOf(valueMapById.getData()), ValuemapDto.class);
            }
        }
        return dataList;
    }

}
